package com.bestcem.xm.om.grpc.service;

import cn.hutool.core.lang.ObjectId;
import com.bestcem.xm.common.core.domain.web.RpcStatusResult;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.enums.ErrorCodeEnum;
import com.bestcem.xm.common.core.uitls.GrpcDateUtil;
import com.bestcem.xm.om.constant.CommonConstant;
import com.bestcem.xm.om.dao.OmUserPackDao;
import com.bestcem.xm.om.dao.UserMmoduleDao;
import com.bestcem.xm.om.dao.UserModulePackDao;
import com.bestcem.xm.om.entity.UserMmodule;
import com.bestcem.xm.om.entity.UserModulepack;
import com.bestcem.xm.om.entity.UserPack;
import com.bestcem.xm.om.enums.UserModuleCategoryEnum;
import com.bestcem.xm.om.grpc.v1.services.Package;
import com.bestcem.xm.om.grpc.v1.services.*;
import com.bestcem.xm.om.service.OrderService;
import com.bestcem.xm.om.service.UserPackService;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 描述信息
 *
 * @author xuan.yang <xuan.yang@idiaoyan.com>
 * @version v1.0
 * @date 2022/4/11 20:14
 */
@Slf4j
@GrpcService
public class OmPackageGrpcService extends PackageServiceGrpc.PackageServiceImplBase {
    @Resource
    private UserPackService userPackService;
    @Resource
    private OmUserPackDao omUserPackDao;
    @Resource
    private UserModulePackDao userModulePackDao;
    @Resource
    private UserMmoduleDao userMmoduleDao;
    @Resource
    private OrderService orderService;

    private static final String NO_PACK_ERROR_MSG = "没有套餐信息";
    private static final String PACK_OR_DOMAIN_ERROR_MSG = "套餐或功能不存在";

    @Override
    public void getPackageByType(GetPackageByTypeRequest request, StreamObserver<GetPackageByTypeResponse> responseObserver) {
        ServiceResult<List<UserPack>> serviceResult = userPackService.findByType(request.getTypeValue());
        // 返回数据
        GetPackageByTypeResponse.Builder builder = GetPackageByTypeResponse.newBuilder();
        // 返回数据
        if (serviceResult.isSuccess()) {
            // 取第一个返回
            builder.setPackage(convertToPackage(serviceResult.getData().get(0)));
            builder.setStatus(RpcStatusResult.success());
        } else {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), serviceResult.getMsg());
            builder.setStatus(RpcStatusResult.error(errMsg));
        }

        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    @Override
    public void getPackageById(GetPackageByIdRequest request, StreamObserver<GetPackageByIdResponse> responseObserver) {
        String id = request.getId();
        GetPackageByIdResponse.Builder builder = GetPackageByIdResponse.newBuilder();
        UserPack userPack = omUserPackDao.getById(id);
        if (Objects.isNull(userPack)) {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), NO_PACK_ERROR_MSG);
            builder.setStatus(RpcStatusResult.error(errMsg));
        } else {
            builder.setStatus(RpcStatusResult.success());
            builder.setPackage(convertToPackage(userPack));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    @Override
    public void getPackageByNameAndType(GetPackageByNameAndTypeRequest request, StreamObserver<GetPackageByNameAndTypeResponse> responseObserver) {
        GetPackageByNameAndTypeResponse.Builder builder = GetPackageByNameAndTypeResponse.newBuilder();
        String name = request.getName();
        int type = request.getTypeValue();
        UserPack userPack = omUserPackDao.getByNameAndType(name, type);
        if (Objects.isNull(userPack)) {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), NO_PACK_ERROR_MSG);
            builder.setStatus(RpcStatusResult.error(errMsg));
        } else {
            builder.setStatus(RpcStatusResult.success());
            builder.setPackage(convertToPackage(userPack));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    @Override
    public void hasCustomerJourneyModule(HasCustomerJourneyModuleRequest request, StreamObserver<HasCustomerJourneyModuleResponse> responseObserver) {
        HasCustomerJourneyModuleResponse.Builder builder = HasCustomerJourneyModuleResponse.newBuilder();
        String packId = request.getId();
        UserModulepack userModulepack = new UserModulepack();
        userModulepack.setPackId(packId);
        userModulepack.setCategory(UserModuleCategoryEnum.MODULE.getIndex());
        List<UserModulepack> userModulepacks = userModulePackDao.queryAllByLimit(userModulepack);
        if (CollectionUtils.isEmpty(userModulepacks)) {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), NO_PACK_ERROR_MSG);
            builder.setStatus(RpcStatusResult.error(errMsg));
        } else {
            Set<String> moduleIds = userModulepacks.stream().map(UserModulepack::getModuleId).collect(Collectors.toSet());
            // 获取客户旅程的id
            UserMmodule userMmodule = new UserMmodule();
            userMmodule.setCode("CUSTOMER_JOURNEY");
            List<UserMmodule> mmodules = userMmoduleDao.queryAllByLimit(userMmodule);
            String mmoduleId = mmodules.get(0).getId();
            builder.setContain(moduleIds.contains(mmoduleId));
            builder.setStatus(RpcStatusResult.success());
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    @Override
    public void hasPackageDomain(HasPackageDomainRequest request, StreamObserver<HasPackageDomainResponse> responseObserver) {
        Boolean contain = userPackService.hasPackageDomain(request.getPackageId(), request.getDomainCode());

        HasPackageDomainResponse.Builder builder = HasPackageDomainResponse.newBuilder();
        if (Objects.isNull(contain)) {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), PACK_OR_DOMAIN_ERROR_MSG);
            builder.setStatus(RpcStatusResult.error(errMsg));
        } else {
            builder.setContain(contain);
            builder.setStatus(RpcStatusResult.success());
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    @Override
    public void getPackageQuota(GetPackageQuotaRequest request, StreamObserver<GetPackageQuotaResponse> responseObserver) {
        GetPackageQuotaResponse.Builder builder = GetPackageQuotaResponse.newBuilder();

        // 参数校验
        String errMsg = "";
        if (!request.hasId() && !request.hasOrgId()) {
            errMsg = "套餐id和机构id不能都为空";
        }
        if (request.hasId() && !ObjectId.isValid(request.getId())) {
            errMsg = "套餐id格式不对";
        }
        if (request.hasOrgId() && !ObjectId.isValid(request.getOrgId())) {
            errMsg = "组织id格式不对";
        }

        if (StringUtils.isNotEmpty(errMsg)) {
            errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.PARAM_ERROR.getMsg(), errMsg);
            builder.setStatus(RpcStatusResult.error(errMsg));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        ServiceResult<String> result = userPackService.getPackageQuota(request.getId(), request.getOrgId());

        if (result.isSuccess()) {
            builder.setQuota(result.getData());
            builder.setStatus(RpcStatusResult.success());
        } else {
            errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), PACK_OR_DOMAIN_ERROR_MSG);
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listPackageIdsByCode(ListPackageIdsByCodeRequest request, StreamObserver<ListPackageIdsByCodeResponse> responseObserver) {
        ServiceResult<List<String>> result = userPackService.listPackageIdsByCode(request.getCode(), request.getCategoryValue());

        ListPackageIdsByCodeResponse.Builder builder = ListPackageIdsByCodeResponse.newBuilder();
        if (result.isSuccess()) {
            builder.addAllIds(result.getData());
            builder.setStatus(RpcStatusResult.success());
        } else {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), PACK_OR_DOMAIN_ERROR_MSG);
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    @Override
    public void getPackageIdByPlatformCode(GetPackageIdByPlatformCodeRequest request,
                                           StreamObserver<GetPackageIdByPlatformCodeResponse> responseObserver) {
        ServiceResult<String> result = userPackService
                .getPackageIdByPlatformCodeAndPackageName(request.getPlatformCode(), request.getPackageName());

        GetPackageIdByPlatformCodeResponse.Builder builder = GetPackageIdByPlatformCodeResponse.newBuilder();
        if (result.isSuccess()) {
            builder.setId(result.getData());
            builder.setStatus(RpcStatusResult.success());
        } else {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), PACK_OR_DOMAIN_ERROR_MSG);
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }


    @Override
    public void upgradePackage(UpgradePackageRequest request,
                               StreamObserver<UpgradePackageResponse> responseObserver) {

        ServiceResult<String> result = orderService.upgradePackage(request.getOrderNo());
        UpgradePackageResponse.Builder builder = UpgradePackageResponse.newBuilder();
        if (result.isSuccess()) {
            builder.setStatus(RpcStatusResult.success());
        } else {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), "套餐升级失败");
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    @Override
    public void deletePackageCacheByOrgId(DeletePackageCacheByOrgIdRequest request,
                                          StreamObserver<DeletePackageCacheByOrgIdResponse> responseObserver) {

        ServiceResult<String> result = userPackService.deletePackageCacheByOrgId(request.getOrgId());
        DeletePackageCacheByOrgIdResponse.Builder builder = DeletePackageCacheByOrgIdResponse.newBuilder();
        if (result.isSuccess()) {
            builder.setStatus(RpcStatusResult.success());
        } else {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), "套餐升级失败");
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    private Package convertToPackage(UserPack userPack) {
        Package.Builder builder = Package.newBuilder()
                .setId(userPack.getId()).setName(userPack.getName());
        if (Objects.nonNull(userPack.getOutName())) {
            builder.setOutName(userPack.getOutName());
        }
        if (Objects.nonNull(userPack.getPrice())) {
            builder.setPrice(userPack.getPrice());
        }
        if (Objects.nonNull(userPack.getUserQuota())) {
            builder.setUserQuota(userPack.getUserQuota());
        }
        if (Objects.nonNull(userPack.getProjectQuota())) {
            builder.setProjectQuota(userPack.getProjectQuota());
        }
        if (Objects.nonNull(userPack.getSurveyQuota())) {
            builder.setSurveyQuota(userPack.getSurveyQuota());
        }
        if (Objects.nonNull(userPack.getMemberIndQuota())) {
            builder.setMemberIndQuota(userPack.getMemberIndQuota());
        }
        if (Objects.nonNull(userPack.getBiDatasourceQuota())) {
            builder.setBiDatasourceQuota(userPack.getBiDatasourceQuota());
        }
        if (Objects.nonNull(userPack.getDefaultFlg())) {
            builder.setDefault(userPack.getDefaultFlg());
        }
        if (Objects.nonNull(userPack.getType())) {
            builder.setTypeValue(userPack.getType());
        }
        if (Objects.nonNull(userPack.getEdition())) {
            builder.setEditionValue(userPack.getEdition());
        }
        if (Objects.nonNull(userPack.getDiscountPrice())) {
            builder.setDiscountPrice(userPack.getDiscountPrice());
        }
        if (Objects.nonNull(userPack.getDiscountBeginTime())) {
            builder.setDiscountBeginTime(GrpcDateUtil.getTimestamp(userPack.getDiscountBeginTime()));
        }
        if (Objects.nonNull(userPack.getDiscountEndTime())) {
            builder.setDiscountEndTime(GrpcDateUtil.getTimestamp(userPack.getDiscountEndTime()));
        }
        if (Objects.nonNull(userPack.getMemberGroupQuota())) {
            builder.setMemberGroupQuota(userPack.getMemberGroupQuota());
        }
        if (Objects.nonNull(userPack.getAdDisplay())) {
            builder.setAdDisplay(userPack.getAdDisplay());
        }
        if (Objects.nonNull(userPack.getNavigationDisplay())) {
            builder.setNavigationDisplay(userPack.getNavigationDisplay());
        }
        return builder.build();
    }
}
